Recibía el error "No se pudo escribir JSON: recursividad infinita" al intentar acceder al punto final http://localhost:8080/categoryOfPermissions . Investigué y encontré varias soluciones aquí ( @JsonManagedReference / @JsonBackReference , @JsonIgnore , @JsonIdentityInfo ), pero ninguna parecía funcionar. Finalmente, encontré una respuesta que decía que era necesario cambiar de Conjunto a Lista para que la solución @JsonIdentityInfo funcionara. Lo probé y realmente comienza a funcionar después de cambiar de Conjunto a Lista.
Pensé que era extraño, pero descubrí algo aún más extraño: después de cambiar de Conjunto a Lista, eliminé las anotaciones @JsonIdentityInfo y todo siguió funcionando. En otras palabras, todo lo que realmente necesitaba hacer era cambiar de Conjunto a Lista para deshacerme de la excepción. Nada más. No se necesita ninguna de las soluciones: @JsonManagedReference / @JsonBackReference , @JsonIgnore , @JsonIdentityInfo .
A continuación se muestra el código que estaba produciendo la excepción. Todo lo que tenía que hacer era cambiar private Set<Permission> permission private List<Permission> permission .
Me gustaría saber por qué, especialmente porque preferiría usar Set, para evitar que Hibernate use el paradigma "Bags" (que puede causar algunos comportamientos indeseables ).
Permiso.java:
@Entity @Data public class Permission{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @NotBlank private String name; @NotNull @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "category_of_permission_id") private CategoryOfPermission categoryOfPermission; }CategoríaDePermiso.java:
@Entity @Data public class CategoryOfPermission{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @NotBlank private String name; @NotNull @OneToMany(mappedBy = "categoryOfPermission", fetch=FetchType.LAZY) private Set<Permission> permission; }CategoryOfPermissionRepo.java:
public interface CategoryOfPermissionRepo extends CrudRepository<CategoryOfPermission, Integer>{ }Esto se debe a que Set en Java usa un contrato de equals para determinar si dos objetos son iguales o no, y la forma en que se implementa el método de equals en la clase Permission (usando lombok ) provoca una recurrencia infinita.
es parte del código generado para el método equals en Permission
Object this$categoryOfPermission = this.getCategoryOfPermission(); Object other$categoryOfPermission = other.getCategoryOfPermission(); if (this$categoryOfPermission == null) { if (other$categoryOfPermission != null) { return false; } } else if (!this$categoryOfPermission.equals(other$categoryOfPermission)) { return false; } y es el código generado para la clase CategoryOfPermission
public boolean equals(final Object o) { if (o == this) { return true; } else if (!(o instanceof CategoryOfPermission)) { return false; } else { CategoryOfPermission other = (CategoryOfPermission)o; if (!other.canEqual(this)) { return false; } else { Object this$id = this.getId(); Object other$id = other.getId(); if (this$id == null) { if (other$id != null) { return false; } } else if (!this$id.equals(other$id)) { return false; } Object this$permission = this.getPermission(); Object other$permission = other.getPermission(); if (this$permission == null) { if (other$permission != null) { return false; } } else if (!this$permission.equals(other$permission)) { return false; } return true; } } } como puede ver, la clase Permission llama al método equals de la clase CategoryOfPermission y CategoryOfPermission llama al método equals de la clase Permision , lo que finalmente causa un problema de desbordamiento de pila.